/*
 * Library.h
 *
 *  Created on: Jul 10, 2009
 *      Author: oferbart
 */

#ifndef LIBRARY_H_
#define LIBRARY_H_

#include <iostream>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
#include <vector>
#include <sstream>
#include "Utils.h"
#include "MetadataBlock.h"
#include "INode.h"
#include "BlockNode.h"
#include "Utils.h"
#include "Log.h"
#include "HD.h"
#include "Directory.h"
#include <utility>
#include <math.h>
#include "UnboundedBlockingQueue.h"
#include "FileDescriptorTable.h"
#include "SysCall.h"
using namespace std;



class Library {
private:
	string _currPath;
	int _pid;
	UnboundedBlockingQueue* _commList;
	FileDescriptorTable* _fdTable;
	SysCall* _sysCall;

	// Process Function in the Library / UI

	int getPremision(string premitions);
	int batch(string batchfile);
	int checkPathFileLength(string path);


public:

	Library(int id, SysCall* sysCall);
	Library(int id, string currPath, SysCall* sysCall);
	Library(int id, Library father, SysCall* sysCall);
	virtual ~Library();

/***********************************************************************
 * 		Process Function in the Library / UI
 ***********************************************************************/

	void sendMessage(string msg);

	int getProcessID();
	string getCurrentPathName();
	void setPathName(string path);
	int processCommand(string command);
	string getFullPathName(string path);
	void* run();




/***********************************************************************
 * 		Library Function / UI
 ***********************************************************************/

	// makes a directory with the given name.
	int mkdir(string dir_name);

	// creates an empty file. Returns a file descriptor <fd>.
	int create(string file_name, string flags);

	// creates a hard link to file-to-link-to. Making a hard link to directories is not allowed.
	int hdlink(string file_to_link_to, string new_file_name);

	// creates a soft link to dest-to-link-to. dest can be either a directory or a file.
	int sflink(string dest_to_link_to, string new_file_name);

	// opens an existing file returning a file descriptor <fd>.
	// The fd returned should always be the lowest one still free. Flag can be set to "read-only" or "read-and-write".
	// Always remember to check when reading or writing that the file was actually opened for that purpose,
	// otherwise return an error. Your flags should be in the exact syntax specified.
	int open(string file_name, string flags);

	// close the file associated with the given file descriptor.
	// Release locks on this file held by this process.
	int close(int fd);

	// Read num-bytes from the file that is identified by fd.
	// Returns the string read, followed by a newline and then the number of bytes that were actually read.
	// Remember read uses the current file pointer to know where to start reading from,
	// and the operation advances the file pointer.
	// The output should be shown on stdout.
	string read(int fd, int num_bytes);

	// writes the string to the file. Returns the number of bytes actually written.
	// Remember write uses the current file pointer to know where to start writing from,
	// and the operation advances the file pointer.
	int write(int fd, string string_to_write);

	// imports a real file from linux's file system from the given address into the file fd.
	// In this way files can be imported into the system.
	int writeFile(int fd, string fileName);

	// locks file, so that only read operations are allowed.
	// There is no limit on the number of processes permitted to read the file.
	// No processes are allowed to write to the file while a process holds a read lock to the file.
	// It is not obligatory to lock the file to read it. You should not block if it is locked, rather return an error.
	int lck_rd(int fd);

	// locks file, so that only one process may hold the lock.
	// This process may write to the file, and no other processes may write to it or read from it.
	// A child does not inherit this lock. It is not obligatory to lock the file to write to it.
	// You should not block if it is locked, rather return an error.
	int lck_wr(int fd);

	// releases the reading lock held by this process. No other process may release this lock.
	int rlslck_rd(int fd);

	// releases the writing lock held by this process. Only the process which locked the file may release the lock.
	int rlslck_wr(int fd);

	// moves the file pointer to the given offset from start of file.
	// If the pointer is set to an offset after the end of the file, this is o.k.
	// /If data is later written at this point, subsequent reads of the data in the gap
	// return bytes of zeros (until data is actually written into the gap).
	// The size of the file should not be updated until data is written to that point.
	int lseek(int fd, int offset);

	// deletes the file.
	int rm(string file_name);

	// deletes the directory. A directory can only be deleted if it is empty.
	int rmdir(string dir_name);

	// recursively deletes directory, all sub-directories and all files.
	// If one of the files is open, terminate and return error.
	// It is o.k. if the system starts deleting files and then finds one open,
	// to then return an error. This means that the command may be executed partially.
	int rmdir_r(string dir_name);

	// returns a list of the files in the given directory, each file in a different line
	// and including the file-name and its size (in bytes). If ls is given without an argument,
	// the ls of the current directory should be returned.
	// Output should be as follows: each file/dir in the given directory in a separate line,
	// directories have the "/" char appended to the end of their name.
	string ls(string dir_name);

	// changes the old-file-name to new file name. This can be just changing its name
	// in the same directory, or even moving the file to a different directory.
	int mv(string old_file_name, string new_file_name);

	// changes current working directory of the current process to new-directory.
	void cd(string new_directory);



};

#endif /* LIBRARY_H_ */
